# src/core/engine/engine.py

from typing import Dict, cast

import pandas as pd
from src.core.backtest.context import Context
from src.core.backtest.portfolio import Portfolio
from src.core.domain.balance import Balance
from src.core.domain.currency import Currency
from src.core.strategy.strategy import Strategy
# 导入所有核心组件
from src.data_access.data_handler import DataHandler


class BacktestEngine:
    """
    事件驱动的回测引擎 (高精度版)。
    协调所有组件，并以高精度处理所有数值传递。
    """

    def __init__(
            self,
            data_handler: DataHandler,
            strategy: Strategy,
            portfolio: Portfolio,
            balance: Balance,
            currencies: Dict[str, Currency]
    ):
        self.data_handler = data_handler
        self.strategy = strategy
        self.portfolio = portfolio
        self.balance = balance
        self.currencies = currencies
        self.master_df = None

    def run(self, symbol: str, start_date: str, end_date: str):
        # 1. 准备数据
        self.master_df = self.data_handler.prepare_data(
            symbol=symbol,
            timeframes=self.strategy.get_required_timeframes(),
            indicators=self.strategy.get_required_indicators(),
            start_date_str=start_date,
            end_date_str=end_date
        )
        # 2. 主循环
        for timestamp, current_bar in self.master_df.iterrows():
            # 使用 cast 向类型检查器明确指出 timestamp 的实际类型是 pd.Timestamp，
            # 从而解决 iterrows() 返回宽泛类型 Hashable 导致的类型警告。
            # 这在运行时没有开销。
            context = Context(self.master_df, cast(pd.Timestamp, timestamp))
            self.portfolio.update_market_value(context)

            self.portfolio.check_risk_management_exits(self.strategy, context)

            self.portfolio.check_strategy_exits(self.strategy, context)

            self.portfolio.check_strategy_entries(self.strategy, context)

        print("Backtest finished.")
        return self.portfolio.closed_positions
